//----------------------------------------------------------------------------
// M A R I T I M E  R E S E A R C H  I N S T I T U T E  N E T H E R L A N D S
//----------------------------------------------------------------------------
// Copyright (C) 2008 - MARIN - All rights reserved - http://www.marin.nl
//----------------------------------------------------------------------------
// Program    : mermaid
// Module     : vbm
// File       : InteractiveWaves.h
//----------------------------------------------------------------------------

#ifndef INTERACTIVEWAVES_H
#define INTERACTIVEWAVES_H

#include <mml/Vector.h>
#include "Array1D.h"
#include "Array2D.h"
#include "defines.h"

class WavesComputer;
class FileReader;

/// encapsulates entire interactive waves computation
class InteractiveWaves
{
public:

    InteractiveWaves();

    virtual ~InteractiveWaves();

    bool setup(const char *parameterfile, const char *solvername, REAL dt, REAL pstart);

    void compute(REAL dt, ///< delta T
                 Array2D<REAL> &pulseField, ///< array with pulse pattern
                 Array2D<REAL> **ppHeight, ///< resulting heightfield
                 Array2D<REAL> **ppNetHeight, ///< resulting heightfield wihout pulse 'hole'
                 Array2D<REAL> **ppSpeed, ///< resulting speed potential
                 double *pCgTime); ///< time used by solver

    void getArea(int *pNx1, int *pNx2, REAL *pdx1, REAL *pdx2, REAL *pg) const;
    void getBathymetry(Array2D<REAL> **ppField, REAL *pMin, REAL *pMax, Array2D<SHORT> **ppWet) const;
    REAL getTime() const;

    void save();

    REAL getHeight(mml::Vector2d const& xy) const;
    REAL getNetHeight(mml::Vector2d const& xy) const;
    REAL getSpeed(mml::Vector2d const& xy) const;

private:

    /// @cond nevercall
    // should never be called
    InteractiveWaves(const InteractiveWaves& m);
    InteractiveWaves & operator =(const InteractiveWaves& m);
    /// @endcond

    void setupArea(FileReader &fr, REAL dt, Initialization *pinit, REAL *ptime, std::string* pfile);
    void setupIncomingWaves(FileReader& fr);
    void drawwaves(REAL Hm0,
                   REAL gam_jon,
                   REAL ome_m,
                   REAL ome_max,
                   REAL theta_m,
                   REAL theta_std,
                   REAL theta_max);
    void correctForPulses(const Array2D<REAL>& pulseField);

    WavesComputer *m_pWC; ///< pointer to waves computer
    Array2D<REAL> *m_ph0; ///< depth table (bathymetry)
    Array2D<REAL> *m_pU1; ///< table with X1 direction flow
    Array2D<REAL> *m_pU2; ///< table with X2 direction flow
    Array2D<SHORT> *m_pwet; ///< wet points (not bool because we have to do arithmetic with it)
    Array2D<REAL> *m_pzeta; ///< waveheights
    //  AM: m_pzetam1 Not reqiured
    Array2D<REAL> *m_pzetam1; ///< previous waveheights
    Array2D<REAL> *m_pphi; ///< speed potential
    // AM: m_pphim1 Not required
    Array2D<REAL> *m_pphim1; ///< previous speed potential
    Array2D<REAL> *m_pzetaNet; ///< waveheights without pulse 'holes'
    int m_Nx1; ///< X1 direction number of points
    int m_Nx2; ///< X2 direction number of points
    REAL m_dx1; ///< horizontal grid spacing [m]
    REAL m_dx2; ///< vertical grid spacing [m]
    REAL m_g; ///< gravitational constant
    REAL m_h0_c; ///< mean depth
    REAL m_U1_c; ///< mean X1 flow
    REAL m_U2_c; ///< mean X2 flow
    int m_wvin_spec_count; ///< number of incoming wave specifications
    Array1D<REAL> m_wvin_spec_ampl; ///< amplitudes
    Array1D<REAL> m_wvin_spec_phase; ///< phases
    Array1D<REAL> m_wvin_spec_freq; ///< frequencies
    Array1D<REAL> m_wvin_spec_dir; ///< directions
    int m_steps; ///< number of simulation steps (0 = infinite)
    int m_skipani; ///< visualize once per skipani steps
    REAL m_h0_min; ///< minimum depth
    REAL m_h0_max; ///< maximum depth
    bool m_save; ///< save the wave field at th end of the computation?
};

#endif // INTERACTIVEWAVES_H
